home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Technical Documentation / PCI Information / PCI Developer’s Kit (disk) / PCI Testing / robix.c < prev   
Encoding:
C/C++ Source or Header  |  1994-06-27  |  11.3 KB  |  477 lines  |  [TEXT/MPS ]

  1. /*
  2. *
  3. * © Copyright 1982-1994, Rob Glanville
  4. *
  5. * by Rob Glanville
  6. *
  7. * 4 Apr 94
  8. *
  9. * robix.c - Debugger for PCI testing
  10. *
  11. */
  12.  
  13. #pragma segment robix
  14.  
  15. #include <stdio.h>
  16.  
  17. #define UInt8        unsigned char        /* Used for casting */
  18. #define UInt16        unsigned short        /* Used for casting */
  19. #define UInt32        unsigned long        /* Used for casting */
  20. #define    PInt8        *(UInt8 *)            /* Used for physical address casting */
  21. #define    PInt16        *(UInt16 *)            /* Used for physical address casting */
  22. #define    PInt32        *(UInt32 *)            /* Used for physical address casting */
  23. #define    VInt8        *(volatile UInt8 *)    /* Used for physical address casting to memory */
  24. #define    VInt16        *(volatile UInt16 *)/* Used for physical address casting to memory */
  25. #define    VInt32        *(volatile UInt32 *)/* Used for physical address casting to memory */
  26. #define True        0xffffffff
  27. #define False        0x00000000
  28. #define CR            0x0d
  29. #define LF            0x0a
  30. #define    Rubout        0x08
  31. #define Tab            0x09
  32. #define NOP            0x00
  33. #define Null        0x00
  34. #define Blank        0x20
  35.  
  36.  
  37. /************************************* ROBIX Constants *********************************************/
  38.  
  39. static const UInt8 Digits[]     = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  40. static const UInt8 Delimiters[] = {0x09,0x0a,0x1b,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
  41.                                    0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x3a,
  42.                                    0x3b,0x3c,0x3d,0x3e,0x40,0x5b,0x5c,0x5d,0x5e,0x5f,
  43.                                    0x00,0x60,0x7b,0x7c,0x7d,0x7e,0x7f,0x3f,0x0d};
  44.  
  45. /************************************* ROBIX Variables *********************************************/
  46.  
  47. UInt8 CommandLine[256];    /* Input buffer                                */
  48. UInt8 delimiter;        /* Delimiter between arguments                */
  49. UInt8 AsciiBuf[19];        /* A buffer for output                        */
  50. UInt8 Argument[0x80];    /* The arguments go here one by one            */
  51. UInt8 TabSize;            /* Size of tab stops                        */
  52. UInt8 KeyboardFrom;        /* Where is the keyboard input coming from? */
  53.  
  54. UInt16 ArgSize;            /* Argument size                            */
  55. UInt16 CPointer;        /* Command pointer                            */
  56.  
  57. UInt32 CommandIndex;    /* The index into command buffer            */
  58. UInt32 number;            /* A place for all numbers input            */
  59. UInt32 BufPtr;            /* Alias buffer pointer for unions            */
  60. UInt32 Base;            /* Base address for all accesses            */
  61. UInt32 Offset;            /* Offset address for some accesses            */
  62. UInt32 accessMethod;    /* Type of hardware access                    */
  63.  
  64.  
  65. /************************************* External Routines **********************************************/
  66. extern void PCIComplianceTest();
  67. extern void DisplayConfiguration();
  68.  
  69. /* Access to PCI configuration space is hardware dependent */
  70. extern UInt8  Read8_Config  (UInt32 RegisterOffset);
  71. extern void   Write8_Config (UInt32 RegisterOffset,UInt8  Data);
  72. extern UInt16 Read16_Config (UInt32 RegisterOffset);
  73. extern void   Write16_Config(UInt32 RegisterOffset,UInt16 Data);
  74. extern UInt32 Read32_Config (UInt32 RegisterOffset);
  75. extern void   Write32_Config(UInt32 RegisterOffset,UInt32 Data);
  76.  
  77.  
  78. UInt8 Int8Read (address) UInt32 address; {
  79.     return(VInt8 address);
  80.     }
  81.  
  82. UInt16 Int16Read (address) UInt32 address; {
  83.     return(VInt16 address);
  84.     }
  85.  
  86. UInt32 Int32Read (address) UInt32 address; {
  87.     return(VInt32 address);
  88.     }
  89.  
  90. void Int8Write (address,data) UInt32 address; UInt8 data; {
  91.     VInt8 address = data;
  92.     }
  93.  
  94. void Int16Write(address,data) UInt32 address; UInt16 data; {
  95.     VInt16 address = data;
  96.     }
  97.  
  98. void Int32Write(address,data) UInt32 address; UInt32 data; {
  99.     VInt32 address = data;
  100.     }
  101.  
  102. UInt8 kbhit() {
  103.     return(Null);
  104.     }
  105.  
  106. UInt8 inchar() {
  107.     return(getchar());
  108.     }
  109.  
  110. void outchar(character) UInt8 character; {
  111.     putchar(character);
  112.     }
  113.  
  114. void printstr(string) UInt8 *string; {
  115.     while (*string != Null) {
  116.         if (*string != '\r')
  117.         outchar(*string++);
  118.         else string++;
  119.         }
  120.     }
  121.  
  122. void SyntaxError() {
  123.     printstr("Syntax error\r\n");
  124.     }
  125.  
  126. /*
  127.  LineIn get input from the user and places it in a command lime buffer
  128.  for later parsing. This is nothing more than echo characters with rubouts
  129.  and tabs.
  130. */
  131. void LineIn() {
  132.     UInt8 character,exit;
  133.     UInt16 index,TabSpace;
  134.     if (delimiter == CR) {
  135.         CommandIndex = Null;
  136.         exit = False;
  137.         CPointer = Null;
  138.         do {
  139.             character = inchar();
  140.             if (character ==  Rubout) {
  141.                 if (CommandIndex > 0) {
  142.                     outchar(Rubout);
  143.                     outchar(Blank);
  144.                     outchar(Rubout);
  145.                     CommandIndex--;
  146.                     }
  147.                 }
  148.             else if (character == CR) {
  149.                 CommandLine[CommandIndex++] = CR;
  150.                 exit = True;        
  151.                 }
  152.             else if (character == Tab) {
  153.                 TabSpace = TabSize - ((CommandIndex+1) % TabSize);
  154.                 for (index=0;index<TabSpace;index++) {
  155.                     outchar(Blank);
  156.                     CommandLine[CommandIndex++] = Blank;
  157.                     }
  158.                 }
  159.             else {
  160.                 CommandLine[CommandIndex++] = character;
  161.                 }
  162.             } while (!exit);
  163.         }
  164.     else delimiter = CR;
  165.     }
  166.  
  167. /*
  168.  Takes a pointer to a character and changes lower case to upper case.
  169. */
  170. void Upper(character) UInt8 *character; {
  171.     if ((*character >= 'a') && (*character <= 'z')) *character -= Blank;
  172.     }
  173.  
  174. /*
  175.  ScanDelimiters simply sets the command line pointer to point to the
  176.  first non delimiter so the user can type garbage and there won't be
  177.  a syntax error.
  178. */
  179. void ScanDelimiters() {
  180.     UInt16 index;
  181.     UInt8 found;
  182.     do {
  183.         found = False;
  184.         if ((CommandLine[CPointer] >= '1') & (CommandLine[CPointer] <= '9')) found = False;
  185.         else if ((CommandLine[CPointer] >= 'a') & (CommandLine[CPointer] <= 'z')) found = False;
  186.         else if ((CommandLine[CPointer] >= 'A') & (CommandLine[CPointer] <= 'Z')) found = False;
  187.         else for (index=0;index<sizeof(Delimiters)-2;index++) {
  188.             if (CommandLine[CPointer] == Delimiters[index]) found = True;
  189.             }
  190.         if (found) CPointer++;
  191.         } while (found);
  192.     }
  193.  
  194. /*
  195.  getarg simply parses the command line and places and arguments in
  196.  a buffer called 'Argument'. Whatever delimiter is found is placed
  197.  in 'delimiter' and the variable 'ArgSize' has the byte count of
  198.  the argument. You make a call to getarg and check the size for non-zero
  199.  to tell when one is found. Keep making calls until you get an argument
  200.  or the delimiter is a cursor return which indicates the end of the
  201.  command line. If you want a number, then use GetValue.
  202. */
  203. void getarg() {
  204.     UInt16 index,ArgPtr;
  205.     UInt8 found;
  206.     ArgPtr = Null;
  207.     do {
  208.         found = False;
  209.         for (index=0;index<sizeof(Delimiters);index++) {
  210.             if (CommandLine[CPointer] == Delimiters[index]) {
  211.                 delimiter = Delimiters[index];
  212.                 if (delimiter != CR) CPointer++;
  213.                 found = True;
  214.                 break;
  215.                 }
  216.             }
  217.         if (!found) Argument[ArgPtr++] = CommandLine[CPointer++];
  218.         } while (!found);
  219.     Argument[ArgPtr] = Null;
  220.     ArgSize = ArgPtr;
  221.     }
  222.  
  223. /*
  224.  GetValue returns true if a hexadecimal number was found in the
  225.  command line. Otherwise it returns false. If a nubmer is found,
  226.  it is placed in the global variable called 'number'. Repeated
  227.  calls to GetValue will get multiple parameters to use in a command. 
  228. */
  229. UInt16 GetValue() {
  230.     UInt8 found;
  231.     UInt16 index,loop;
  232.     if (delimiter == ',') return(False);
  233.     found = False;
  234.     number = Null;
  235.     do {
  236.         getarg(); /* Get one argument from the command line */
  237.         if (ArgSize) {
  238.             /* Check for all digits in the argument */
  239.             for (index=0;index<ArgSize;) {
  240.                 Upper(&Argument[index]);
  241.                 found = False;
  242.                 for (loop=0;loop<0x10;loop++) {
  243.                     if (Argument[index] == Digits[loop]) {
  244.                         Argument[index] = loop;
  245.                         found = True;
  246.                         break;
  247.                         }
  248.                     }
  249.                 if (!found) break;
  250.                 else index++;
  251.                 }
  252.             /* Convert ascii to hex */
  253.             if (found) for (index=0;index<ArgSize;index++) {
  254.                 number = ((number * 0x10) + Argument[index]);
  255.                 }
  256.             }
  257.         } while ((!found) && (delimiter != CR) && (delimiter != ','));
  258.     return(found);
  259.     }
  260.  
  261. void nibble(data) UInt8 data; {
  262.     if (data > 9) outchar(data + '7');
  263.     else outchar(data + '0');
  264.     }
  265.  
  266. void byteout(data) UInt8 data; {
  267.     nibble((data / 0x10) & 0x0f);
  268.     nibble(data & 0x0f);
  269.     }
  270.  
  271. void wordout(data) UInt16 data; {
  272.     byteout((UInt8)(data / 0x100) & 0xff);
  273.     byteout((UInt8)data & 0xff);
  274.     }
  275.  
  276. void longout(data) UInt32 data; {
  277.     wordout((UInt16)(data / 0x10000) & 0xffff);
  278.     wordout((UInt16)data & 0xffff);
  279.     }
  280.  
  281. void decout(data) UInt32 data; {
  282.     UInt8 Decimal;
  283.     Decimal = data / 1000000000;
  284. /*    nibble(Decimal); */
  285.     data = data % 1000000000;
  286.     Decimal = data / 100000000;
  287. /*    nibble(Decimal); */
  288.     data = data % 100000000;
  289.     Decimal = data / 10000000;
  290. /*    nibble(Decimal); */
  291.     data = data % 10000000;
  292.     Decimal = data / 1000000;
  293. /*    nibble(Decimal); */
  294.     data = data % 1000000;
  295.     Decimal = data / 100000;
  296. /*    nibble(Decimal); */
  297.     data = data % 100000;
  298.     Decimal = data / 10000;
  299. /*    nibble(Decimal); */
  300.     data = data % 10000;
  301.     Decimal = data / 1000;
  302. /*    nibble(Decimal); */
  303.     data = data % 1000;
  304.     Decimal = data / 100;
  305. /*    nibble(Decimal); */
  306.     data = data % 100;
  307.     Decimal = data / 10;
  308.     nibble(Decimal);
  309.     data = data % 10;
  310.     nibble(data);
  311.     }
  312.  
  313. void crlf() {
  314.     printstr("\n");
  315.     }
  316.  
  317. /************************************* Commands *********************************************/
  318.  
  319. /* Fill in the help menu when you add a new command */
  320. void Help() {
  321.     printstr("?) Print this menu\r\n");
  322. /*    printstr("A) \r\n"); */
  323.     printstr("B) Byte read or write to config space (offset,data)\r\n"); /**/
  324. /*    printstr("C) \r\n"); */
  325.     printstr("D) Display configuration space\r\n");
  326. /*    printstr("E) \r\n"); */
  327. /*    printstr("F) \r\n"); */
  328. /*    printstr("G) \r\n"); */
  329. /*    printstr("H) \r\n"); */
  330. /*    printstr("I) \r\n"); */
  331. /*    printstr("J) \r\n"); */
  332. /*    printstr("K) \r\n"); */
  333.     printstr("L) Long read or write to config space (offset,data)\r\n"); /**/
  334. /*    printstr("M) \r\n"); */
  335. /*    printstr("N) \r\n"); */
  336. /*    printstr("O) \r\n"); */
  337. /*    printstr("P) \r\n"); */
  338. /*    printstr("Q) \r\n"); */
  339. /*    printstr("R) \r\n"); */
  340.     printstr("S) Short read or write to config space (offset,data)\r\n"); /**/
  341. /*    printstr("T) \r\n"); */
  342. /*    printstr("U) \r\n"); */
  343. /*    printstr("V) \r\n"); */
  344. /*    printstr("W) \r\n"); */
  345. /*    printstr("X) \r\n"); */
  346. /*    printstr("Y) \r\n"); */
  347. /*    printstr("Z) \r\n"); */
  348.     }
  349.  
  350. /************************************* Main Loop ********************************************/
  351.  
  352.  
  353. void main() {
  354.     UInt32 Address;
  355.     UInt8 Exit;
  356.     delimiter = CR;
  357.     TabSize = 8;
  358.     Exit = False;
  359.     printf("PCI Compliance test, Configuration Space\n\nBy Rob Glanville\n\n");
  360.     PCIComplianceTest(); /* Call the test sequencer and run some tests */
  361.     while (!Exit) {
  362.         if (delimiter == CR) printstr(">");
  363.         LineIn();
  364.         ScanDelimiters(); /* Point to first non Blank */
  365.         Upper(&CommandLine[CPointer]);
  366.         switch(CommandLine[CPointer++]) {
  367.             case '?' :
  368.                 Help();
  369.                 break;
  370.             case CR :
  371.                 break;
  372.             case 'A' :
  373.                 break;
  374.             case 'B' :
  375.                 if (GetValue()) Address = number;
  376.                 else Address = 0;
  377.                 if (GetValue()) {
  378.                     Write8_Config(Address,number);
  379.                     }
  380.                 else {byteout(Read8_Config(Address));crlf();}
  381.                 break;
  382.             case 'C' :
  383.                 break;
  384.             case 'D' :
  385.                 DisplayConfiguration();
  386.                 break;
  387.             case 'E' :
  388.                 break;
  389.             case 'F' :
  390.                 break;
  391.             case 'G' :
  392.                 break;
  393.             case 'H' :
  394.                 break;
  395.             case 'I' :
  396.                 break;
  397.             case 'J' :
  398.                 break;
  399.             case 'K' :
  400.                 break;
  401.             case 'L' :
  402.                 if (GetValue()) Address = number;
  403.                 else Address = 0;
  404.                 if (GetValue()) {
  405.                     Write32_Config(Address,number);
  406.                     }
  407.                 else {longout(Read32_Config(Address));crlf();}
  408.                 break;
  409.             case 'M' :
  410.                 break;
  411.             case 'N' :
  412.                 break;
  413.             case 'O' :
  414.                 break;
  415.             case 'P' :
  416.                 break;
  417.             case 'Q' :
  418.                 break;
  419.             case 'R' :
  420.                 break;
  421.             case 'S' :
  422.                 if (GetValue()) Address = number;
  423.                 else Address = 0;
  424.                 if (GetValue()) {
  425.                     Write16_Config(Address,number);
  426.                     }
  427.                 else {wordout(Read16_Config(Address));crlf();}
  428.                 break;
  429.             case 'T' :
  430.                 break;
  431.             case 'U' :
  432.                 break;
  433.             case 'V' :
  434.                 break;
  435.             case 'W' :
  436.                 break;
  437.             case 'X' :
  438.                 break;
  439.             case 'Y' :
  440.                 break;
  441.             case 'Z' :
  442.                 break;
  443.             default :
  444.                 printstr("Unknown command\r\n");
  445.                 delimiter = CR;
  446.                 break;
  447.             }
  448.         }
  449.     }
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.